package org.mikrosopht.movievote.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.http.client.URL;
import com.google.gwt.json.client.JSONException;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.MouseListenerAdapter;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.AttachDetachException;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class MovieVote implements EntryPoint {
  private MovieList movieList;

  /**
   * This is the entry point method.
   */
  public void onModuleLoad() {
    GetUserInfoAndAddMovieList();
  }

  private void GetUserInfoAndAddMovieList() {
    // Retrieve user info
    String url = URL.encode(MovieVoteConstants.USER_INFO_JSON_URL);
    RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, url);
    try {
      builder.sendRequest(null, new UserInfoHandler());
    } catch (RequestException e) {
      Window.alert("Couldn't retrieve JSON: " + e);
    }
  }

  public static void redirectToLogin() {
    Window.open(MovieVoteConstants.LOGIN_URL, "_self", null);
  }

  private class UserInfoHandler implements RequestCallback {
    public void onError(Request request, Throwable exception) {
      Window.alert("Couldn't retrieve JSON: " + exception);
    }
    public void onResponseReceived(Request request, Response response) {
      if (response.getStatusCode() == 200) {
        try {
          JSONObject object = JSONParser.parse(response.getText()).isObject();
          MovieListSort sort1 = MovieListSort.fromString(object.get("sort1").isString().stringValue());
          MovieListSort sort2 = MovieListSort.fromString(object.get("sort2").isString().stringValue());
          String weighting = object.get("weighting_description").isString().stringValue();
          String username = object.get("username").isString().stringValue();
          if (Integer.parseInt(object.get("unrated_screenings").isString().stringValue()) > 0) {
            // There are movies screened but not yet rated.
            DialogBox dialog = createNotifyUnratedDialog();
            dialog.center();
            dialog.show();
            sort1 = MovieListSort.SCREENING_DATE_DESCENDING;
          }
          HTML weightingLink = HTML.wrap(DOM.getElementById("weighting_description"));
          weightingLink.setHTML("<a href=\"" + MovieVoteConstants.USER_STATS_URL + "\">" + weighting + "</a>");
          
          Label usernameLabel = Label.wrap(DOM.getElementById("username"));
          usernameLabel.setText(username);

          RootPanel movieListSlot = RootPanel.get("movie_list");
          movieList = new MovieList(sort1, sort2);
          try {
            movieListSlot.add(movieList);
            movieList.onFirstClick();
          } catch (AttachDetachException e) {
            Window.alert("Attach exception!");
            for (Throwable actual: e.getCauses()) {
              Window.alert("Attach exception: " + actual);
            }
            Window.alert("Done with exceptions");
          }
        } catch (JSONException e) {
          redirectToLogin();
        }
      } else {
        Window.alert("Couldn't retrieve JSON: " + response.getStatusText());
      } 
    }
  }

  private DialogBox createNotifyUnratedDialog() {
    final DialogBox dialogBox = new DialogBox(true, false);
    HorizontalPanel dialogContents = new HorizontalPanel();
    dialogContents.setSpacing(8);
    Image leftImage = new Image(MovieVoteConstants.UNRATED_DIALOG_LEFT_IMG);
    dialogContents.add(leftImage);
    dialogBox.setWidget(dialogContents);

    VerticalPanel dialogWords = new VerticalPanel();
    dialogWords.setSpacing(8);
    dialogContents.add(dialogWords);

    HTML details = new HTML("O HAI. I has noticed you have watched some movies with us but have " +
                            "not yet rated all of them. <br>I have switched your view to your attended " +
                            "movies. <br>Please rate them all by clicking on the stars in the RIGHTMOST column. " +
                            "<br>Click on the 'Show only my screenings' checkbox above when done.");
    dialogWords.add(details);
    dialogWords.setCellHorizontalAlignment(details, HasHorizontalAlignment.ALIGN_CENTER);
    Button ok = new Button("KTHXBAI");
    ok.addClickListener(new ClickListener() {
      public void onClick(Widget sender) {
        dialogBox.hide();
      }
    });
    dialogWords.add(ok);
    dialogWords.setCellHorizontalAlignment(ok, HasHorizontalAlignment.ALIGN_CENTER);
    return dialogBox;
  }
}
